package aino;

public class Attribute {
    int nameIndex;
    int length;
    byte[] info;
    Class cls;

    public Attribute(int ni, int l, Class c) {
	nameIndex = ni;
	length = l;
	cls = c;
	info = new byte[l];
    }

    public void addInfo(int i, byte inf) {
	info[i] = inf;
    }

    public int getConstantValue() {
	return (getByte(0)<<8)|getByte(1);
    }

    public int getMaxStack() {
	return (getByte(0)<<8)|getByte(1);
    }

    public int getMaxLocals() {
	return (getByte(2)<<8)|getByte(3);
    }

    public int getByte(int i) {
	if (length == 0) Log.out("*** getByte("+i+"), but len = 0");
	int retval = info[i]&0xff;
	//if (retval < 0) retval += 256;
	return retval;
    }

    public int getSignByte(int i) {
	if (length == 0) Log.out("*** getByte("+i+"), but len = 0");
	int retval = info[i];
	//if (retval < 0) retval += 256;
	return retval;
    }

    public int getShort(int i) {
	return (getByte(i)<<8)|getByte(i+1);
    }

    public int getInt(int i) {
	return (getByte(i)<<24)|(getByte(i+1)<<16)|(getByte(i+2)<<8)|getByte(i+3);
    }

    public int getLineNumber(int pc) {
	int exps_p = 8 + getCodeLength();
	int exptbllen = getShort(exps_p);
	int attrscnt_p = 8 * exptbllen + 2 + exps_p;
	int attrs = getShort(attrscnt_p);
	int i = attrscnt_p + 2;
	while (i < length) {
	    int nameix = getShort(i);
	    int len = getInt(i+2);
	    i += 6;
	    if (cls.getConst(nameix).equals("LineNumberTable")) {
		int linenumtbllen = getShort(i);
		for (int j = 0; j < linenumtbllen; j++) {
		    int c = getShort(i+2+4*j);
		    if (c == pc) return getShort(i+4+4*j);
		    if (c > pc) return 0;
		}
	    }
	    i += len;
	}
	return 0;
    }

    public int getCodeLength() {
	return (getByte(4)<<24)|(getByte(5)<<16)|(getByte(6)<<8)|getByte(7);
    }

    public int getCodeByte(int i) {
	int retval = getByte(i+8);
	return retval;
    }

    public int getSignCodeByte(int i) {
	int retval = getSignByte(i+8);
	return retval;
    }

    public byte getCodeByte1(int i) {
	return info[i+8];
    }

    public int getExceptionTableLength() {
	int i = 8 + getCodeLength();
	return (getByte(i)<<8)|getByte(i+1);
    }

    public int getAttributesCount() {
	int i = 8 + getCodeLength() + getExceptionTableLength()*8;
	return (getByte(i)<<8) | getByte(i+1);
    }
}

